package com.samphanie.auiu.library.restful

import androidx.annotation.IntDef
import com.samphanie.auiu.library.restful.annotation.CacheStrategy
import java.lang.IllegalStateException
import java.lang.reflect.Method
import java.lang.reflect.Type
import java.net.URLEncoder

/**
 * @author Dries
 **/
open class AuiuRequest {

    private var cacheStrategyKey: String = ""
    var cacheStrategy: Int = CacheStrategy.NET_ONLY

    @METHOD
    var httpMethod: Int = 0  // GET POST
    var formPost: Boolean = true    // 是否表单提交，POST请求有效
    var headers: MutableMap<String, String>? = null  // 请求头
    var parameters: MutableMap<String, String>? = null  // 请求入参
    var domainUrl: String? = null    // 域名
    var relativeUrl: String? = null  // 相对路径
    var returnType: Type? = null     // restful 方法的泛型返回值

    @IntDef(value = [METHOD.GET, METHOD.POST])
    annotation class METHOD {
        companion object {
            const val GET = 0
            const val POST = 1
        }
    }

    // 返回请求完整Url
    fun endPointUrl(): String {
        if (relativeUrl == null) {
            throw IllegalStateException("relative url must not be null")
        }

        if (relativeUrl!!.startsWith("/")) {
            return domainUrl + relativeUrl
        }

        relativeUrl = "/$relativeUrl"

        val indexOf = domainUrl!!.indexOf("/")

        return domainUrl!!.substring(0, indexOf) + relativeUrl
    }

    fun addHeader(name: String, value: String) {
        if (headers == null) {
            headers = mutableMapOf()
        }

        headers!![name] = value
    }

    fun getCacheKey(): String {
        if (!cacheStrategyKey.isNullOrBlank()) {
            return cacheStrategyKey
        }
        val builder = StringBuilder()
        val endUrl = endPointUrl()
        builder.append(endUrl)
        if (endUrl.indexOf("?") > 0 || endUrl.indexOf("&") > 0) {
            builder.append("&")
        } else {
            builder.append("?")
        }

        if (parameters != null) {
            for ((key, value ) in parameters!!) {
                try {
                    val encodeValue = URLEncoder.encode(value, "UTF-8")
                    builder.append(key).append("=").append(encodeValue).append("&")
                } catch (e: Exception) { }
            }
            builder.deleteCharAt(builder.length - 1)
            cacheStrategyKey = builder.toString()
        } else {
            cacheStrategyKey = endUrl
        }

        return cacheStrategyKey
    }
}